package com.odontosis.view.maladireta;

import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.lowagie.text.BadElementException;
import com.lowagie.text.Cell;
import com.lowagie.text.Document;
import com.lowagie.text.Font;
import com.lowagie.text.PageSize;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.Table;
import com.lowagie.text.rtf.RtfWriter;
import com.odontosis.entidade.Paciente;
import com.odontosis.ioc.ContainerIoc;
import com.odontosis.service.PacienteService;
import com.odontosis.util.StringUtilsOdontosis;
import com.odontosis.view.OdontosisAction;

public class AcaoMalaDireta  extends OdontosisAction<PacienteService> {
	
	private static final int PACIENTES_POR_PAGINA = 20;


	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormMalaDireta formulario = (FormMalaDireta) form;
		if(StringUtils.isEmpty(formulario.getMetodo()))
		{
			return onIniciarTela(mapping, form, request, response);
		} else if (formulario.getMetodo().equals("imprimir")) {
			return onImpressao(mapping, form, request, response);
		} else if (formulario.getMetodo().equals("visualizar")) {
			return onGerarArquivo(mapping, form, request, response);
		}
		return onIniciarTela(mapping, form, request, response);
		
	}
	
	
	public ActionForward onIniciarTela(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		return mapping.getInputForward();
	}
	
	public ActionForward onImpressao(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormMalaDireta formulario = (FormMalaDireta) form;
		PacienteService pacienteService = ContainerIoc.getPacienteService();
		Date inicio = StringUtilsOdontosis.StringToDate(formulario.getDataInicio());
		Date fim = StringUtilsOdontosis.StringToDate(formulario.getDataFim());
		String nomePaciente = StringUtilsOdontosis.isVazia(formulario.getNomePaciente()) ? "" : formulario.getNomePaciente() ;
		List<Paciente> listagemPacientes = pacienteService.buscarPacientesPorAniversario(inicio, fim, nomePaciente);
		List<String> valores = new ArrayList<String>();
		for (Paciente paciente : listagemPacientes) {
			valores.add(paciente.getNome());
			String endereco = paciente.getRuaResidencial() != null ? paciente.getRuaResidencial() : "";
			if(!StringUtilsOdontosis.isVazia(paciente.getNumResidencial())) {
				endereco += ", " + paciente.getNumResidencial(); 
			}
			valores.add(endereco);
			valores.add("Bairro: " + paciente.getBairroResidencial());
			valores.add("CEP: " + paciente.getCepResidencial());
			valores.add(paciente.getCidadeResidencial() + " - " +  paciente.getUfResidencial());
		}
		
		if(listagemPacientes.isEmpty()) {
			Collection<String> erros = new ArrayList<String>();
			erros.add("Não há dados a serem exibidos para os filtros informados.");
			request.setAttribute("mensagens", erros);
			return mapping.getInputForward();
		} 
		
		request.setAttribute("valores", valores);
		
		return mapping.findForward("impressao");
	}
	
	
	public ActionForward onGerarArquivo(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormMalaDireta formulario = (FormMalaDireta) form;
		PacienteService pacienteService = ContainerIoc.getPacienteService();
		Date inicio = StringUtilsOdontosis.StringToDate(formulario.getDataInicio());
		Date fim = StringUtilsOdontosis.StringToDate(formulario.getDataFim());
		String nomePaciente = StringUtilsOdontosis.isVazia(formulario.getNomePaciente()) ? "" : formulario.getNomePaciente() ;
		List<Paciente> listagemPacientes = pacienteService.buscarPacientesPorAniversario(inicio, fim, nomePaciente);

		if(listagemPacientes.isEmpty()) {
			Collection<String> erros = new ArrayList<String>();
			erros.add("Não há dados a serem exibidos para os filtros informados.");
			request.setAttribute("mensagens", erros);
			return mapping.getInputForward();
		} 
		
		gerarRelatorio(listagemPacientes, inicio, fim, response);
		
		return null;
	}
	
	
	public void gerarRelatorio(List<Paciente> resultado,Date inicio, Date fim, HttpServletResponse response){
		try{
			//fontes
			Font fontItem = new Font(Font.TIMES_ROMAN, 8, Font.NORMAL);
	        Font fontTotal = new Font(Font.TIMES_ROMAN, 8, Font.BOLD);
	        Font fontePequena = new Font(Font.TIMES_ROMAN, 5, Font.BOLD);
	        Font fonteMenor = new Font(Font.TIMES_ROMAN, 3, Font.NORMAL);
	        
			//inicializa documento
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			Document document = new Document(); //margens esquerda, direita, superior, inferior
			document.setPageSize(PageSize.A4);
			document.setMargins(0, 0, 0, 0);
			RtfWriter.getInstance(document, baos);
			//rtfWriter.setMargins(0, 0, 0, 0);
			//rtfWriter.setPageSize(new Rectangle(250,878));
			document.open();
						
			//cria a tabela
			float [] tamanhos = {2,13,6,1};
			Table table = criarObjetoTabela(4, tamanhos);
			//table.setWidth(81);
			int i = 0; 
			for (Paciente paciente : resultado) {
				i++;
				Cell nome = new Cell();
				nome.setBorderColor(new Color(255,255,255));
				nome.addElement(new Phrase(paciente.getNome(),fontTotal));
				nome.addElement(new Phrase("\n" + paciente.getRuaResidencial(),fontItem));
				if(!StringUtilsOdontosis.isVazia(paciente.getNumResidencial())) { 
					nome.addElement(new Phrase( " N. " +  paciente.getNumResidencial(),fontItem));
				}
				nome.addElement(new Phrase("\nBairro: " + paciente.getBairroResidencial(),fontItem));
				nome.addElement(new Phrase("\nCEP: "+paciente.getCepResidencial() ,fontItem));
				nome.addElement(new Phrase("\n" + paciente.getCidadeResidencial(),fontItem));
				nome.addElement(new Phrase("\n" ,fontItem));
				nome.addElement(new Phrase("\n" ,fontItem));
				nome.addElement(new Phrase("\n" ,fontePequena));
				nome.addElement(new Phrase("\n" ,fonteMenor));
				switch(i) {
					case 5: 
					case 6:
					case 13:
					case 14:
					case 17:
					case 18:
						nome.addElement(new Phrase("\n" ,fontItem));
							break;
				}
				
				if(i % 2 != 0) {
					table.addCell(getCelulaVazia());
				}
				table.addCell(nome);
				if(i % 2 == 0) {
					table.addCell(getCelulaVazia());
				}
				if(i % PACIENTES_POR_PAGINA == 0) {
					document.add(table);
					document.newPage();
					table = criarObjetoTabela(4, tamanhos);
				}
			}
			
			if(i % PACIENTES_POR_PAGINA != 0) {
				if(i % 2 != 0) {
					table.addCell(getCelulaVazia());
					table.addCell(getCelulaVazia());
				}
				document.add(table);
			}
			
			
			document.close();
			response.setContentType("application/rtf");
			response.setContentLength(baos.size());
			ServletOutputStream out = response.getOutputStream();
			baos.writeTo(out);
			out.flush();
			
		
		}catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	private Cell getCelulaVazia() {
		Cell nome = new Cell();
		nome.setBorderColor(new Color(255,255,255));
		return nome;
	}
	
	
	private Table criarObjetoTabela(int numColunas, float[] headerWidths) {
	        try {
	            Table aTable = new Table(numColunas);

	            aTable.setPadding(0);
	            aTable.setSpacing(0);

	            aTable.setWidths(headerWidths);

	            //aTable.widthPercentage();
	            aTable.setWidth(100);
	            aTable.setBorder(0);

	            aTable.setSpaceBetweenCells(0);

	            aTable.setDefaultCellBorderWidth(0);
	            aTable.setBorder(0);
	            aTable.setBorderColor(new Color(255,255,255));
	            
	            aTable.setAlignment(Table.ALIGN_LEFT);

	            return aTable;
	        } catch (BadElementException e) {
	            throw new RuntimeException("Erro definindo largura do cabeçalho", e);
	        }
	    }

}

